package com.eliza.v.http.templating

import com.eliza.v.http.VertxTools
import io.vertx.core.AbstractVerticle
import io.vertx.core.AsyncResult
import io.vertx.core.Promise
import io.vertx.core.buffer.Buffer
import io.vertx.core.http.HttpMethod
import io.vertx.core.json.JsonArray
import io.vertx.core.json.JsonObject
import io.vertx.ext.web.Router
import io.vertx.ext.web.RoutingContext
import io.vertx.ext.web.common.template.TemplateEngine
import io.vertx.ext.web.templ.freemarker.FreeMarkerTemplateEngine
import io.vertx.ext.web.templ.handlebars.HandlebarsTemplateEngine
import io.vertx.ext.web.templ.jade.JadeTemplateEngine
import io.vertx.ext.web.templ.mvel.MVELTemplateEngine
import io.vertx.ext.web.templ.pebble.PebbleTemplateEngine
import io.vertx.ext.web.templ.rocker.RockerTemplateEngine
import io.vertx.ext.web.templ.thymeleaf.ThymeleafTemplateEngine


/*-*- coding:utf-8 -*-
 * @Author  : debi
 * @Time    : 2/5/22
 * @Software: IntelliJ IDEA
 */
class Template : AbstractVerticle() {
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            VertxTools.runVerticalList(listOf(Template::class.java))
        }
    }


    override fun start(startPromise: Promise<Void>?) {
        super.start(startPromise)
//        mvel() //err
        rocker() //err


//        thymeleaf()
//        pebble()
//        freemarker()
//        handlebars()
//        jade()


    }

    private fun freemarker() {

        // To simplify the development of the web components we use a Router to route all HTTP requests
        // to organize our code in a reusable way.
        val router = Router.router(vertx)
        var routePath = "/Template/freemarker"

        // In order to use a template we first need to create an engine
        val engine = FreeMarkerTemplateEngine.create(vertx)

        // Entry point to the application, this will render a custom template.
        router.get(routePath).handler { rc: RoutingContext ->
            // we define a hardcoded title for our application
            val data = JsonObject().put("name", "Vert.x Web").put("path", rc.request().path())

            // and now delegate to the engine to render it.
            val path = "templates/freemarker/index.ftl"
            engine.render(data, path) { res: AsyncResult<Buffer?> ->
                if (res.succeeded()) {
                    rc.response().end(res.result())
                } else {
                    rc.fail(res.cause())
                }
            }
        }

        // start a HTTP web server on port 8080
        VertxTools.result(vertx, this, routePath, router, 8080)
    }

    private fun handlebars() {
        var routePath = "/Template/handlebars"

        val router: Router = Router.router(vertx)
        val engine: HandlebarsTemplateEngine = HandlebarsTemplateEngine.create(vertx)
        router.route(routePath).method(HttpMethod.GET).method(HttpMethod.POST).handler { rc ->
            val data: JsonObject = JsonObject().put("title", "Seasons of the year")
            // we define a hardcoded array of json objects
            val seasons = JsonArray()
            seasons.add(JsonObject().put("name", "Spring"))
            seasons.add(JsonObject().put("name", "Summer"))
            seasons.add(JsonObject().put("name", "Autumn"))
            seasons.add(JsonObject().put("name", "Winter"))
            data.put("seasons", seasons)


            var templates = "templates/handlebars/index.hbs"
            engine.render(data, templates) { res ->
                if (res.succeeded()) {
                    rc.response().end(res.result())
                } else {
                    rc.fail(res.cause())
                }
            }

        }

        VertxTools.result(vertx, this, routePath, router, 8080)
    }

    private fun jade() {
        var routePath = "/Template/jade"

        val router: Router = Router.router(vertx)
        val engine: JadeTemplateEngine = JadeTemplateEngine.create(vertx)

        router.route(routePath).method(HttpMethod.GET)
            .method(HttpMethod.POST).handler { rc ->
                val data: JsonObject = JsonObject().put("name", "Vert.x Web")
                var path = "templates/jade/index.jade"
                engine.render(data, path) { res ->
                    if (res.succeeded()) {
                        rc.response().end(res.result())
                    } else {
                        rc.fail(res.cause())
                    }
                }
            }
        VertxTools.result(vertx, this, "jade", router, 8080)
    }

    private fun mvel() {

        val router = Router.router(vertx)
        var routePath = "/Template/mvel"


        val engine: TemplateEngine = MVELTemplateEngine.create(vertx)
        val context = JsonObject()
            .put("foo", "badger")
            .put("bar", "fox")
        var path = "templates/mvel/templates"
        context.put("context", JsonObject().put("path", "/mvel-template2.templ"))

        router.route(routePath).handler { rc: RoutingContext ->
            rc.put("title", "Vert.x Web Example Using Rocker")
            rc.put("name", "Rocker")
            engine.render(context, "templates/mvel/templates/mvel-template2.templ") { res: AsyncResult<Buffer> ->
                if (res.succeeded()) {
                    rc.response().end(res.result())
                } else {
                    rc.fail(res.cause())
                }
            }
        }

        VertxTools.result(vertx, this, routePath, router, 8080)

    }

    private fun pebble() {
        val router = Router.router(vertx)

        val engine = PebbleTemplateEngine.create(vertx)

        router.get("/*").handler { rc: RoutingContext ->
            val data = JsonObject()
                .put("name", "Vert.x Web")
                .put("path", rc.request().path())
//            templates/pebble/index.peb
            engine.render(data, "templates/pebble/index.peb") { res: AsyncResult<Buffer?> ->
                if (res.succeeded()) {
                    rc.response().end(res.result())
                } else {
                    rc.fail(res.cause())
                }
            }
        }

        VertxTools.result(vertx, this, "pebble", router, 8080)

    }

    private fun rocker() {
        val router = Router.router(vertx)


        var routePath = "/Template/rocker"
        val engine: RockerTemplateEngine = RockerTemplateEngine.create()
        router.route(routePath).handler { rc: RoutingContext ->

            var filePath = "templates/rocker/index.rocker.html"
            val data = JsonObject()
                .put("foo", "badger")
                .put("bar", "fox")
                .put("context", JsonObject().put("path", "/TestRockerTemplate2"));


            engine.render(data, filePath) { res ->
                if (res.succeeded()) {
                    rc.response().end(res.result())
                } else {
                    rc.fail(res.cause())
                }
            }

        }



        VertxTools.result(vertx, this, routePath, router, 8080)

    }

    private fun thymeleaf() {
        val router = Router.router(vertx)
        var routePath = "/Template/thymeleaf"

        // In order to use a Thymeleaf template we first need to create an engine
        val engine = ThymeleafTemplateEngine.create(vertx)

        // Entry point to the application, this will render a custom JADE template.
        router.get(routePath).handler { rc: RoutingContext ->
            // we define a hardcoded title for our application
            val data = JsonObject()
                .put("welcome", "Hi there! $routePath")

            // and now delegate to the engine to render it.
            var path = "templates/thymeleaf/index.html"

            engine.render(data, path) { res: AsyncResult<Buffer?> ->
                if (res.succeeded()) {
                    rc.response().end(res.result())
                } else {
                    rc.fail(res.cause())
                }
            }
        }


        VertxTools.result(vertx, this, routePath, router, 8080)

    }


}